Creating a Console UI–Based Front End

Create a new Console Application named AutoLotCUIClient. After you create your new project, be sure to add a reference to your AutoLotDAL.dll assembly, as well as System.Configuration.dll. Next, add the following using statements to your C# code file:

using AutoLotConnectedLayer;
using System.Configuration;
using System.Data;

Now insert a new App.config file into your project that contains a <connectionStrings> element, which you will use to connect to your instance of the AutoLot database, as in this example:

<configuration>
    <connectionStrings>
        <add name ="AutoLotSqlProvider" connectionString =
        "Data Source=(local)\SQLEXPRESS;
        Integrated Security=SSPI;Initial Catalog=AutoLot"/>
    </connectionStrings>
</configuration>

Implementing the Main() Method

The Main() method is responsible for prompting the user for a specific course of action and executing that request using a switch statement. This program allows the user to enter the following commands:

Each possible option is handled by a unique static method within the Program class. The next snippet shows the complete implementation of Main(). Notice that each method invoked from the do/while loop (with the exception of the ShowInstructions() method) takes an InventoryDAL object as its sole parameter:

static void Main(string[] args)
{
    Console.WriteLine("***** The AutoLot Console UI *****\n");

    // Get connection string from App.config.
    string cnStr =
        ConfigurationManager.ConnectionStrings["AutoLotSqlProvider"].ConnectionString;
    bool userDone = false;
    string userCommand = "";

    // Create our InventoryDAL object.
    InventoryDAL invDAL = new InventoryDAL();
    invDAL.OpenConnection(cnStr);

    // Keep asking for input until user presses the Q key.
    try
    {
        ShowInstructions();
        do
        {
            Console.Write("\nPlease enter your command: ");
            userCommand = Console.ReadLine();
            Console.WriteLine();
            switch (userCommand.ToUpper())
            {
                case "I":
                    InsertNewCar(invDAL);
                    break;
                case "U":
                    UpdateCarPetName(invDAL);
                    break;
                case "D":
                    DeleteCar(invDAL);
                    break;
                case "L":
                    ListInventory(invDAL);
                    break;
                case "S":
                    ShowInstructions();
                    break;
                case "P":
                    LookUpPetName(invDAL);
                    break;
                case "Q":
                    userDone = true;
                    break;
                default:
                    Console.WriteLine("Bad data! Try again");
                    break;
            }
        } while (!userDone);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
    finally
    {
        invDAL.CloseConnection();
    }
}

Implementing the ShowInstructions() Method

The ShowInstructions() method does what you would expect:

private static void ShowInstructions()
{
    Console.WriteLine("I: Inserts a new car.");
    Console.WriteLine("U: Updates an existing car.");
    Console.WriteLine("D: Deletes an existing car.");
    Console.WriteLine("L: Lists current inventory.");
    Console.WriteLine("S: Shows these instructions.");
    Console.WriteLine("P: Looks up pet name.");
    Console.WriteLine("Q: Quits program.");
}

Implementing the ListInventory() Method

You could implement the ListInventory() method in either of two ways, based on how you constructed your data access library. Recall that the GetAllInventoryAsDataTable() method of InventoryDAL returns a DataTable object. You could implement this approach like this:

private static void ListInventory(InventoryDAL invDAL)
{
    // Get the list of inventory.
    DataTable dt = invDAL.GetAllInventoryAsDataTable();
    
    // Pass DataTable to helper function to display.
    DisplayTable(dt);
}

The DisplayTable() helper method displays the table data using the Rows and Columns properties of the incoming DataTable (again, you will learn the full details of the DataTable object the next chapter, so don’t fret over the details):

private static void DisplayTable(DataTable dt)
{
    // Print out the column names.
    for (int curCol = 0; curCol < dt.Columns.Count; curCol++)
    {
        Console.Write(dt.Columns[curCol].ColumnName + "\t");
    }
    Console.WriteLine("\n----------------------------------");

    // Print the DataTable.
    for (int curRow = 0; curRow < dt.Rows.Count; curRow++)
    {
        for (int curCol = 0; curCol < dt.Columns.Count; curCol++)
        {
            Console.Write(dt.Rows[curRow][curCol].ToString() + "\t");
        }
        Console.WriteLine();
    }
}

If you would prefer to call the GetAllInventoryAsList() method of InventoryDAL, you could implement a method named ListInventoryViaList():

private static void ListInventoryViaList(InventoryDAL invDAL)
{
    // Get the list of inventory.
    List<NewCar> record = invDAL.GetAllInventoryAsList();

    foreach (NewCar c in record)
    {
        Console.WriteLine("CarID: {0}, Make: {1}, Color: {2}, PetName: {3}",
            c.CarID, c.Make, c.Color, c.PetName);
    }
}

Implementing the DeleteCar() Method

Deleting an existing automobile is as simple as asking the user for the ID of the car and passing this to the DeleteCar() method of the InventoryDAL type:

private static void DeleteCar(InventoryDAL invDAL)
{
    // Get ID of car to delete.
    Console.Write("Enter ID of Car to delete: ");
    int id = int.Parse(Console.ReadLine());

    // Just in case you have a referential integrity
    // violation!
    try
    {
        invDAL.DeleteCar(id);
    }
    catch(Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

Implementing the InsertNewCar() Method

Inserting a new record into the Inventory table is a simple matter of asking the user for the new bits of data (using Console.ReadLine() calls) and passing this data into the InsertAuto() method of InventoryDAL:

private static void InsertNewCar(InventoryDAL invDAL)
{
    // First get the user data.
    int newCarID;
    string newCarColor, newCarMake, newCarPetName;

    Console.Write("Enter Car ID: ");
    newCarID = int.Parse(Console.ReadLine());

    Console.Write("Enter Car Color: ");
    newCarColor = Console.ReadLine();

    Console.Write("Enter Car Make: ");
    newCarMake = Console.ReadLine();

    Console.Write("Enter Pet Name: ");
    newCarPetName = Console.ReadLine();

    // Now pass to data access library.
    invDAL.InsertAuto(newCarID, newCarColor, newCarMake, newCarPetName);
}

Recall that you overloaded InsertAuto() to take a NewCar object, rather than a set of independent arguments. Thus, you could have implemented InsertNewCar() like this:

private static void InsertNewCar(InventoryDAL invDAL)
{
    // First get the user data.
...
    // Now pass to data access library.
    NewCar c = new NewCar { CarID = newCarID, Color = newCarColor,
        Make = newCarMake, PetName = newCarPetName };
    invDAL.InsertAuto(c);
}

Implementing the UpdateCarPetName() Method

The implementation of UpdateCarPetName() looks similar:

private static void UpdateCarPetName(InventoryDAL invDAL)
{
    // First get the user data.
    int carID;
    string newCarPetName;

    Console.Write("Enter Car ID: ");
    carID = int.Parse(Console.ReadLine());
    Console.Write("Enter New Pet Name: ");
    newCarPetName = Console.ReadLine();

    // Now pass to data access library.
    invDAL.UpdateCarPetName(carID, newCarPetName);
}

Implementing LookUpPetName()

Obtaining the pet name of a given automobile works similarly to the previous methods; this is so because the data access library encapsulates all of the lower-level ADO.NET calls:

private static void LookUpPetName(InventoryDAL invDAL)
{
    // Get ID of car to look up.
    Console.Write("Enter ID of Car to look up: ");
    int id = int.Parse(Console.ReadLine());
    Console.WriteLine("Petname of {0} is {1}.",
        id, invDAL.LookUpPetName(id));
}

With this, your console-based front end is finished! It’s time to run your program and test each method. Here is some partial output that tests the L, P, and Q commands:

***** The AutoLot Console UI *****
I: Inserts a new car.
U: Updates an existing car.
D: Deletes an existing car.
L: Lists current inventory.
S: Shows these instructions.
P: Looks up pet name.
Q: Quits program.

Please enter your command: L

CarID     Make     Color     PetName
----------------------------------
83     Ford     Rust     Rusty
107     Ford     Red     Snake
678     Yugo     Green     Clunker
904     VW     Black     Hank
1000     BMW     Black     Bimmer
1001     BMW     Tan     Daisy
1992     Saab     Pink     Pinkey

Please enter your command: P

Enter ID of Car to look up: 904
Petname of 904 is Hank.

Please enter your command: Q

Press any key to continue . . .

Source Code You can find the AutoLotCUIClient application under the Chapter 21 subdirectory.